package com.jasiri.project.lib.dev.data

import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.graphics.Point
import android.hardware.Sensor
import android.hardware.SensorManager
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.os.Build
import android.os.SystemClock
import android.provider.Settings
import android.view.WindowManager
import com.google.gson.Gson
import com.jasiri.project.lib.dev.util.checkToString
import com.jasiri.project.lib.dev.util.formatZipString
import com.jasiri.project.lib.dev.util.getCommonData6
import org.json.JSONArray
import org.json.JSONObject
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.util.Locale
import java.util.TimeZone
import kotlin.math.pow
import kotlin.math.sqrt

/**
 * hardware
 */
class JasiriSysDataT3(val context: Context) {

    fun getSubmitDataT3(): String? {
        return try {
           val data = hashMapOf<String, Any>().apply {
                put("operatingSystem", "ANDROID")
                put("model", Build.MODEL.toString())
                put("serial", "")
                put("productionDate", Build.TIME.toString())
                put("sdkVersion", Build.VERSION.SDK_INT.toString())
                put("phoneType", getSysT3Data13(context))
                put("versionCode", getSysT3Data14(context))
                put("versionName", getSysT3Data15(context))
                put("androidId", getSysT3Data16(context))
                put("telephony", "")
                put("isVpn", getSysT3Data11(context))
                put("isProxyPort", getSysT3Data12())
                put("isDebug", getSysT3Data17(context))
                put("simState", getSysT3Data18(context))
                put("root", getSysT3Data6())
                put("physicalSize", getSysT3Data10(context))
                put("displayLanguage", getSysT3Data19())
                put("iso3Language", getSysT3Data20())
                put("iso3Country", getSysT3Data21())
                put("networkOperatorName", "")
                put("networkType", getCommonData6(context))
                put("timeZoneId", getSysT3Data22())
                put("elapsedRealtime", getSysT3Data23())
                put("sensorList", getSysT3Data1(context))
                put("lastBootTime", getSysT3Data24())
                put("rootJailbreak", getSysT3Data6())
                put("keyboard", getSysT3Data7(context))
                put("isSimulator", getSysT3Data8())
                put("dbm", getSysT3Data9(context)) //
                put("phoneNumber", "")
            }
            Gson().toJson(data).trim().formatZipString()

        } catch (e: java.lang.Exception) {
            null
        }
    }

    private fun getSysT3Data1(context: Context): String {
        val jsonArray = JSONArray()
        try {
            val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
            val sensors = sensorManager.getSensorList(Sensor.TYPE_ALL)
            for (sensor in sensors) {
                val jsonObject = JSONObject().apply {
                    put("type", sensor.type.toString())
                    put("name", sensor.name.checkToString())
                    put("version", sensor.version.toString())
                    put("maxRange", sensor.maximumRange.toString().checkToString())
                    put("vendor", sensor.vendor.checkToString())
                    put("minDelay", sensor.minDelay.toString().checkToString())
                    put("power", sensor.power.toString().checkToString())
                    put("resolution", sensor.resolution.toString().checkToString())
                }
                jsonArray.put(jsonObject)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return jsonArray.toString()
    }

    private fun getSysT3Data2(): Boolean {
        val buildTags = Build.TAGS
        return buildTags != null && buildTags.contains("test-keys")
    }

    private fun getSysT3Data3(): Boolean {
        val paths = arrayOf(
            "/system/app/Superuser.apk",
            "/sbin/su",
            "/system/bin/su",
            "/system/xbin/su",
            "/data/local/xbin/su",
            "/data/local/bin/su",
            "/system/sd/xbin/su",
            "/system/bin/failsafe/su",
            "/data/local/su"
        )
        return paths.any { File(it).exists() }
    }

    private fun getSysT3Data4(): Boolean {
        var process: Process? = null
        return try {
            process = Runtime.getRuntime().exec(arrayOf("/system/xbin/which", "su"))
            val reader = BufferedReader(InputStreamReader(process.inputStream))
            reader.readLine() != null
        } catch (t: Throwable) {
            false
        } finally {
            process?.destroy()
        }
    }

    private fun getSysT3Data5(): Boolean {
        return getSysT3Data2() || getSysT3Data3() || getSysT3Data4()
    }

    private fun getSysT3Data6(): String {
        return if (getSysT3Data5()) "YES" else "NO"
    }


    private fun getSysT3Data7(context: Context): String {
        return try {
            val config = context.resources.configuration
            config.keyboard.toString().checkToString()
        } catch (e: Exception) {
            e.printStackTrace()
            ""
        }
    }

    private fun getSysT3Data8(): String {
        val isMatch = (
                Build.BRAND.startsWith("generic") ||
                        Build.FINGERPRINT.startsWith("generic") ||
                        Build.FINGERPRINT.startsWith("unknown") ||
                        Build.HARDWARE.contains("goldfish") ||
                        Build.HARDWARE.contains("ranchu") ||
                        Build.MODEL.contains("google_sdk") ||
                        Build.MODEL.contains("Emulator") ||
                        Build.MODEL.contains("Android SDK built for x86") ||
                        Build.MANUFACTURER.contains("Genymotion") ||
                        (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) ||
                        "google_sdk" == Build.PRODUCT)

        return if (isMatch) "YES" else "NO"
    }

    @SuppressLint("MissingPermission")
    private fun getSysT3Data9(context: Context): String {
        return ""
    }


    private fun getSysT3Data10(context: Context): String {
        var sizeStr = ""
        try {
            val point = Point()
            val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
            wm.defaultDisplay.getRealSize(point)
            val dm = context.resources.displayMetrics
            val x = (point.x / dm.xdpi.toDouble()).pow(2.0)
            val y = (point.y / dm.ydpi.toDouble()).pow(2.0)
            val screenInches = sqrt(x + y)
            sizeStr = screenInches.toString()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return sizeStr
    }

    private fun getSysT3Data11(context: Context): String {
        return try {
            val connectivityManager =
                context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
            if (activeNetwork != null && activeNetwork.type == ConnectivityManager.TYPE_VPN) {
                "YES"
            } else {
                "NO"
            }
        } catch (e: Exception) {
            e.printStackTrace()
            "NO"
        }
    }

    private fun getSysT3Data12(): String {
        return try {
            val proxyHost = System.getProperty("http.proxyHost")
            val proxyPort = System.getProperty("http.proxyPort")
            if (proxyHost != null && proxyPort != null) {
                "YES"
            } else {
                "NO"
            }
        } catch (e: Exception) {
            e.printStackTrace()
            "NO"
        }
    }

    private fun getSysT3Data13(context: Context): String {
        return ""
    }

    private fun getSysT3Data14(context: Context): String {
        return try {
            val packageInfo = context.packageManager.getPackageInfo(
                context.packageName,
                PackageManager.GET_ACTIVITIES
            )
            packageInfo.versionCode.toString()
        } catch (e: Exception) {
            e.printStackTrace()
            "1"
        }
    }

    private fun getSysT3Data15(context: Context): String {
        return try {
            val packageInfo = context.packageManager.getPackageInfo(
                context.packageName,
                PackageManager.GET_ACTIVITIES
            )
            packageInfo.versionName ?: "1.0"
        } catch (e: Exception) {
            e.printStackTrace()
            "1.0"
        }
    }

    @SuppressLint("HardwareIds")
    private fun getSysT3Data16(context: Context): String {
        return Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID) ?: ""
    }

    private fun getSysT3Data17(context: Context): String {
        return try {
            val applicationInfo = context.applicationInfo
            if (applicationInfo != null && applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE != 0) {
                "YES"
            } else {
                "NO"
            }
        } catch (e: Exception) {
            e.printStackTrace()
            "NO"
        }
    }

    private fun getSysT3Data18(context: Context): String {
        return ""
    }

    private fun getSysT3Data19(): String {
        return try {
            Locale.getDefault().displayLanguage
        } catch (e: Exception) {
            e.printStackTrace()
            ""
        }
    }

    private fun getSysT3Data20(): String {
        return try {
            Locale.getDefault().isO3Language
        } catch (e: Exception) {
            e.printStackTrace()
            ""
        }
    }

    private fun getSysT3Data21(): String {
        return try {
            Locale.getDefault().isO3Country
        } catch (e: Exception) {
            e.printStackTrace()
            ""
        }
    }

    private fun getSysT3Data22(): String {
        return try {
            TimeZone.getDefault().id
        } catch (e: Exception) {
            e.printStackTrace()
            ""
        }
    }

    private fun getSysT3Data23(): String {
        return try {
            SystemClock.elapsedRealtime().toString()
        } catch (e: Exception) {
            e.printStackTrace()
            ""
        }
    }

    private fun getSysT3Data24(): String {
        return try {
            (System.currentTimeMillis() - SystemClock.elapsedRealtime()).toString()
        } catch (e: Exception) {
            e.printStackTrace()
            ""
        }
    }
}